package orm

import (
	"fmt"
	"gitee.com/golang-lib/go-framework/utils"
	"gorm.io/gorm"
	"reflect"
	"strings"
)

func Where(db *gorm.DB, table string, src interface{}) *gorm.DB {
	m := ToSqlMap(table, src)
	if m == nil {
		return db
	}
	for key, val := range m {
		if val == nil {
			db = db.Where(key)
		} else {
			db = db.Where(key, val)
		}
	}
	return db
}

func ToSqlMap(table string, src interface{}) map[string]interface{} {
	if src == nil {
		return nil
	}

	m := make(map[string]interface{})

	value := reflect.ValueOf(src)
	tp := reflect.TypeOf(src)

	if value.Kind().String() == "ptr" {
		value = value.Elem()
		tp = tp.Elem()
	}

	if value.Kind().String() == "struct" {
		num := value.NumField()
		for i := 0; i < num; i++ {
			if utils.IsBlank(value.Field(i)) {
				continue
			}

			if value.Kind() == reflect.Slice {
				m[table+"."+tp.Field(i).Name+" in ?"] = value.Field(i).Interface()
				continue
			}

			sqlTag := tp.Field(i).Tag.Get("sql")
			if sqlTag == "-" {
				continue
			}

			field := tp.Field(i).Tag.Get("json")
			if tp.Field(i).Tag.Get("field") != "" {
				field = tp.Field(i).Tag.Get("field")
			}

			if sqlTag == "" {
				m[table+"."+field+" = ?"] = value.Field(i).Interface()
			} else {
				sqlTag = strings.ReplaceAll(sqlTag, "?", fmt.Sprint(value.Field(i).Interface()))
				m[table+"."+field+" "+sqlTag] = nil
			}
		}
	}
	return m
}
